﻿using System;
using System.Configuration;
using System.Linq;

namespace Lbb.Configuration
{
    /// <summary>
    /// 配置助理
    /// </summary>
    /// <author>Chiron</author>
    public static class ConfigHelper
    {
        #region Private fields
        private const string keySE = ":";
        #endregion Private fields

        #region Methods

        #region GetConfigKey
        /// <summary>
        /// 取得配置键串
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static string GetConfigKey(params string[] key)
        {
            if (key == null || key.Length == 0) return null;
            return key.Aggregate((d, e) => d + keySE + e);
        }

        /// <summary>
        /// 取得配置键串
        /// </summary>
        /// <param name="vKey">配置键串</param>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static bool GetConfigKey(out string vKey, params string[] key)
        {
            return !string.IsNullOrEmpty((vKey = GetConfigKey(key)));
        }
        #endregion GetConfigKey

        #region GetAppSettingValue
        /// <summary>
        /// 取得程序配置值。
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static string GetAppSettingValue(params string[] key)
        {
            string vKey;
            return GetConfigKey(out vKey, key) ? ConfigurationManager.AppSettings[vKey] : null;
        }

        /// <summary>
        /// 取得程序配置值。
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static T GetAppSettingValue<T>(params string[] key) where T : struct
        {
            return GetAppSettingValue(default(T), key);
        }

        /// <summary>
        /// 取得程序配置值。
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="defaultValue">默认值</param>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static T GetAppSettingValue<T>(T defaultValue, params string[] key) where T : struct
        {
            var type = typeof(T);
            string vKey;

            if (!GetConfigKey(out vKey, key)) return defaultValue;

            var strValue = ConfigurationManager.AppSettings[vKey];
            if (string.IsNullOrEmpty(strValue)) return defaultValue;

            T value = defaultValue;
            if (type.IsEnum) Enum.TryParse<T>(strValue, out value);
            else if (type.IsPrimitive) value = (T)Convert.ChangeType(strValue, type);
            else throw new Exception("遇到了未处理的类型！");

            return value;
        }
        #endregion GetAppSettingValue

        /// <summary>
        /// 取得数据库连接配置
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static ConnectionStringSettings GetConnectionStringSettings(params string[] key)
        {
            string vKey;
            return GetConfigKey(out vKey, key) ? ConfigurationManager.ConnectionStrings[vKey] : null;
        }

        /// <summary>
        /// 取得数据库连接串
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns></returns>
        public static string GetConnectionString(params string[] key)
        {
            string vKey;
            var connss = GetConfigKey(out vKey, key) ? ConfigurationManager.ConnectionStrings[vKey] : null;
            if (connss == null) throw new ConfigurationErrorsException(string.Format("找不到配置名为{0}的数据库连接配置!", vKey));
            return connss.ConnectionString;
        }
        #endregion Methods

    }
}
